﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace Sublimation
{
    public class Tower : GameObject
    {
        protected TowerEnergy energy;
        public TowerEnergy Energy
        {
            get { return this.energy; }
        }
        protected Shield shield; //starts with 0 energy so permanently collapsed and components can add or equivalent
        public Shield Shield
        {
            get { return this.shield; }
        }
        protected Player owner;
        protected Texture2D tower_top;
        protected Texture2D tower_bottom;

        protected Slot[] slots = new Slot[6]; //XXX:lets make these separate variables for clarity - then again we can loop over these

        //the maximum diameter of a tower
        public const float RADIUS = 50;

        // shouldn't all of this be in the tower energy?
        // im going moving it there
        protected int nbEnergy;
        public int NbEnergy
        {
            get { return nbEnergy; }
            set {nbEnergy = value; }
        }
        protected int production;

        public Tower(WorldProperties worldProperties, Player owner, Vector2 position)
            : base(worldProperties)
        {
            LoadContent();
            Scale = 1.0f;

            this.worldProperties = worldProperties;
            SetOriginToCentre();
            Position = position;
            Rotation = 0;
            nbEnergy = 0;
            production = 100;

            this.energy = new TowerEnergy(worldProperties, this);
            this.shield = new Shield(worldProperties, this);
            this.owner = owner;

            slots[0] = new SlotEnergy(worldProperties, SlotKind.Energy_transmition, this);
            slots[1] = new SlotWeapon(worldProperties, SlotKind.Base_weapon, this);

            // make sure it loads and draws
            DrawOrder = 50;
            UpdateOrder = 50;
            Visible = true;
            Enabled = true;
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            nbEnergy+= production;
        }

        protected override void LoadContent()
        {
            base.LoadContent();

            tower_bottom = Game.Content.Load<Texture2D>("Sprites/tower_bottom");
            Sprite = Game.Content.Load<Texture2D>("Sprites/tower_top");

            CollisionRadius = 40f;
        }

        public override void Draw(GameTime gameTime)
        {
            
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            spriteBatch.Draw(tower_bottom, position, null, Color.White, 0, origin, 1, SpriteEffects.None, 1);
            spriteBatch.End();
            base.Draw(gameTime);
        }

        public override void ApplyDamage(float damage)
        {
            base.ApplyDamage(damage);

            // remove damage from shield if there is any
            if (Shield != null && Shield.ShieldEnergy > 0)
            {
                Shield.ApplyDamage(damage);
            }
            else
            {
                Energy.ApplyDamage(damage);
            }
        }

        public override void Kill()
        {
            base.Kill();

            // cleanup components
            if (Shield != null) Shield.Kill();
            if (Energy != null) Energy.Kill();

            //TODO: kill slots
            foreach(Slot slot in slots) {
                if (slot != null) slot.Kill();
            }

            // spawn an explosion
            new Explosion(worldProperties, this, 1.5f);

            //TODO: victory conditions
            int towerCount = 0;
            foreach (Player player in worldProperties.Players)
            {
                foreach (Tower tower in player.Towers)
                {
                    if (tower != this) towerCount++;
                }
            }
            if (towerCount == 0) worldProperties.EndGame();
        }

        public override void GarbageCollect()
        {
            base.GarbageCollect();

            // remove from player's tower list
            owner.Towers.Remove(this);
        }
    }
}
